<?php
/**
 * Created by PhpStorm.
 * User: dong
 * Date: 2018/5/27
 * Time: 13:50
 */
namespace App\Services\ThirdPayments\Recharge;

use App\Exceptions\RechargeGatewayException;
use App\Lib\Code;
use App\Lib\PaymentMap;
use App\Lib\ThirdPartyMap;
use App\Models\RechargeOrder;
use App\Services\ThirdPayments\BankTraits\GFTBankMap;
use App\Services\ThirdPayments\Contracts\Actions\HrefRedirectAction;
use App\Services\ThirdPayments\Contracts\Actions\QrCodeAction;
use App\Services\ThirdPayments\Contracts\QRCapable;
use App\Services\ThirdPayments\Contracts\RechargeBaseAbstract;
use App\Services\ThirdPayments\Contracts\WAPable;

class GFTPayment extends RechargeBaseAbstract implements QRCapable, WAPable
{
    use GFTBankMap;

    protected $gw_pay = 'http://go-pay.cn/Payment';
    protected $gw_query = 'http://go-pay.cn/apiquery';

    public function callback(array $data)
    {
        // TODO: Implement callback() method.
        if ($this->veryCallbackSign($data)) {
            if ($data['status'] == 1)
                return true;
        }
        return false;
    }

    public function veryCallbackSign(array $data)
    {
        // TODO: Implement veryCallbackSign() method.
        $signStr = "";
        $signStr .= 'mch_id=' . $data['mch_id'] . '&';
        $signStr .= 'status=' . $data['status'] . '&';
        $signStr .= 'sdpayno=' . $data['sdpayno'] . '&';
        $signStr .= 'out_trade_no=' . $data['out_trade_no'] . '&';
        $signStr .= 'total_fee=' . $data['total_fee'] . '&';
        $signStr .= 'service=' . $data['service'] . '&';
        $signStr .= $this->getMchKey();
        return md5($signStr);
    }

    public function getOrderNoFromCallback(array $data)
    {
        // TODO: Implement getOrderNoFromCallback() method.
        return $data['out_trade_no'];
    }

    public function getOrderAmtFromCallback(array $data)
    {
        // TODO: Implement getOrderAmtFromCallback() method.
        return $data['total_fee'];
    }

    public function getThirdNoFromCallback(array $data)
    {
        return $data['sdpayno'];
    }


    /**
     * @return mixed
     */
    public function getIdentify(): string
    {
        // TODO: Implement getIdentify() method.
        return ThirdPartyMap::GFTONG;
    }

    /**
     *  needs child to achieve
     */
    public function initPaymentMap(): array
    {
        // TODO: Implement initPaymentMap() method.
        return [
            PaymentMap::WX   => 'weixin',
            PaymentMap::WX_WAP => 'wxwap',
            PaymentMap::ALI => 'aliwap',
            PaymentMap::ALI_WAP  => 'aliwap',
            PaymentMap::QQ => 'qqrcode',
            PaymentMap::QQ_WAP => 'qqwap',
            PaymentMap::BANK => 'bank'
        ];
    }

    public function query(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement query() method.
        $this->setParameter('version', '3.6');
        $this->setParameter('mch_id', $this->getMchId());
        $this->setParameter('out_trade_no', $rechargeOrder->plat_no);
        $this->setParameter('reqtime', date('YmdHis'));
        $this->setParameter('get_code', 'json');
        $this->setParameter('sign', $this->querySign());
        $res = curlHttp($this->getGwQuery(), $this->getParameters());
        if ($res['http_code'] == 200) {
            $body = json_decode($res['body'], true);
            if ($body['status'] == 1) return true;
            else return $body['msg'];
        }
        return $res['body'];
    }

    public function bankHref(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement bankHref() method.
        $this->initParameters($rechargeOrder);
        $res = curlHttp($this->getGwPay(), $this->getParameters());
        if ($this->curlResVerify($this, $res)) {
            $body = json_decode($res['body'], true);
            if (array_key_exists('url', $body)) {
                return new QrCodeAction($body['url']);
            } else {
                return new HrefRedirectAction($body['pay_url']);
            }
            throw  new RechargeGatewayException($this, '取码接口错误', $body['msg'], Code::RECHARGE_THIRD_LOG);
        }
    }

    public function scanCode(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement scanCode() method.
    }

    public function paySign(): string
    {
        // TODO: Implement paySign() method.
        $signStr = "";
        $signStr .= 'version=' . $this->getParameter('version') . '&';
        $signStr .= 'mch_id=' . $this->getParameter('mch_id') . '&';
        $signStr .= 'total_fee=' . $this->getParameter('total_fee') . '&';
        $signStr .= 'out_trade_no=' . $this->getParameter('out_trade_no') . '&';
        $signStr .= 'callback_url=' . $this->getParameter('callback_url') . '&';
        $signStr .= 'jump_url=' . $this->getParameter('jump_url') . '&';
        $signStr .= $this->getMchKey();
        return md5($signStr);
    }

    public function querySign(): string
    {
        // TODO: Implement querySign() method.
        $signStr = "";
        $signStr .= 'version=' . $this->getParameter('version') . '&';
        $signStr .= 'mch_id=' . $this->getParameter('mch_id') . '&';
        $signStr .= 'out_trade_no=' . $this->getParameter('out_trade_no') . '&';
        $signStr .= 'reqtime=' . $this->getParameter('reqtime') . '&';
        $signStr .= $this->getMchKey();
        return md5($signStr);
    }

    public function showSuccess(): string
    {
        // TODO: Implement showSuccess() method.
        return 'success';
    }

    public function initParameters(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement initParameters() method.
        $mchData = $rechargeOrder->order_data;
        $this->setParameter('service', $this->getPaymentMap($mchData['recharge_type']));
        $this->setParameter('version', '3.6');
        $this->setParameter('mch_id', $this->getMchId());
        $this->setParameter('out_trade_no', $rechargeOrder->plat_no);
        $this->setParameter('total_fee', $rechargeOrder->order_amt);
        if ($mchData['recharge_type'] == PaymentMap::BANK) {
            $this->setParameter('bankcode', $this->getBank($mchData['bank_code']));
        }
        $this->setParameter('callback_url', $this->getCallbackUrl());
        $this->setParameter('jump_url', $this->getReturnUrl());
        $this->setParameter('get_code', 'json');
        $this->setParameter('body', array_key_exists('body', $mchData) ? $mchData['body'] : 'merchant_order');
        $this->setParameter('sign', $this->paySign());
    }

    public function qrCode(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement qrCode() method.
        $this->initParameters($rechargeOrder);
        $res = curlHttp($this->getGwPay(), $this->getParameters());
        if ($this->curlResVerify($this, $res)) {
            $body = json_decode($res['body'], true);
            if ($body['status'] == 1) {
                if (array_key_exists('url', $body)) {
                    return new QrCodeAction($body['url']);
                } else {
                    return new HrefRedirectAction($body['pay_url']);
                }
            }
            throw  new RechargeGatewayException($this, '取码接口错误', $body['msg'], Code::RECHARGE_THIRD_LOG);
        }
    }

    public function wapReq(RechargeOrder $rechargeOrder)
    {
        // TODO: Implement wapReq() method.
        $this->initParameters($rechargeOrder);
        $res = curlHttp($this->getGwPay(), $this->getParameters());
        if ($this->curlResVerify($this, $res)) {
            $body = json_decode($res['body'], true);
            if (array_key_exists('url', $body)) {
                return new HrefRedirectAction($body['url']);
            } else {
                return new HrefRedirectAction($body['pay_url']);
            }
            throw  new RechargeGatewayException($this, '取码接口错误', $body['msg'], Code::RECHARGE_THIRD_LOG);
        }
    }
}
